﻿/* Camera Martix 实现忆遍：
 * https://blog.csdn.net/shi_tou_ge/article/details/114805763
 *
 *
 * 
 */

using System;
using System.Collections.Generic;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.Rendering;

public class TestCommandBufferTransformVert : MonoBehaviour
{

    public enum UpdateMode
    {
        Update,
        LastUpdate,
        FixedUpdate
    }

    //public RenderTexture rt;
    public Camera m_camera;
    public GameObject cube;
    public Shader cubeShader;
    //public Shader sampleShader;
    private CommandBuffer cb;

    private Mesh quad;
    public TestCommandBuffer.MatrixMode matrixMode = TestCommandBuffer.MatrixMode.TransformVert ;
    public Vector3 offsetPos;
    public UpdateMode updateMode = UpdateMode.Update;
    private List<Vector3> sourceVerts;
    private void Update()
    {
        if(updateMode==UpdateMode.Update)
            DrawMesh();
    }

    private void FixedUpdate()
    {
        if(updateMode==UpdateMode.FixedUpdate)
            DrawMesh();
    }

    private void LateUpdate()
    {
        if(updateMode==UpdateMode.LastUpdate)
            DrawMesh();
    }

    void DrawMesh()
    {
        MeshFilter mf = cube.GetComponent<MeshFilter>();
        Material mat = new Material(cubeShader);
        Matrix4x4 m = Matrix4x4.identity;
        if (matrixMode ==TestCommandBuffer.MatrixMode.TransformVert)
        {
            //测试往只后移10格
            //m.SetTRS(new Vector3(0, 0, 10), Quaternion.identity, Vector3.one);
            m.SetTRS(cube.transform.localPosition,quaternion.identity,Vector3.one);

            //测试Camera matrix 不知道原理
//            Matrix4x4 oneMatrix = m_camera.worldToCameraMatrix;
//            oneMatrix.SetTRS(cube.transform.localPosition,quaternion.identity, Vector3.one);

            Matrix4x4 oneMatrix = m;
            //oneMatrix.SetTRS(offsetPos,quaternion.identity, Vector3.one );
            oneMatrix.SetTRS(cube.transform.localPosition,quaternion.identity, Vector3.one );
            
            List<Vector3> verts = new List<Vector3>();
            //绘制 Sprite 的4个边
//            var min = spriteBounds.min;
//            var max = spriteBounds.max;
//            var v0 = min;
//            var v1 = new Vector3(min.x, max.y, min.z);
//            var v2 = max;
//            var v3 = new Vector3(max.x, min.y, min.z);
            foreach (var vert in     sourceVerts)
            {
              //verts.Add(m.MultiplyPoint(vert));
              verts.Add(oneMatrix.MultiplyPoint(vert));
            }
            mf.mesh.SetVertices(verts);
            List<Color> colors = new List<Color>();
            colors.AddRange(mf.mesh.colors);
            List<Vector2> uvSets = new List<Vector2>();
            uvSets.AddRange(mf.mesh.uv);
            List<int> triangleSets = new List<int>();
            triangleSets.AddRange(mf.mesh.triangles);
            
            mf.mesh.Clear();
            mf.mesh.SetVertices(verts);
            mf.mesh.SetColors(colors);
            mf.mesh.SetUVs(0,uvSets);
            mf.mesh.SetTriangles(triangleSets,0);

            
            cb.DrawMesh(mf.mesh, Matrix4x4.identity, mat);
        }else
        {
//        m.SetTRS(new Vector3(0, 0, 10), Quaternion.identity, Vector3.one);
//        //m.SetTRS(cube.transform.position,cube.transform.rotation,cube.transform.localScale);
            m.SetTRS(cube.transform.localPosition, Quaternion.identity, Vector3.one);
            cb.DrawMesh(mf.mesh, m, mat);
        }
    }

    void Start()
    {
        cb = new CommandBuffer();
        cb.name = "testCb";
        //rt = new RenderTexture(m_camera.pixelWidth, m_camera.pixelHeight, 24);
        //cb.SetRenderTarget(rt);
        //cb.ClearRenderTarget(true, true, Color.black);
        MeshFilter mf = cube.GetComponent<MeshFilter>();
        sourceVerts = new List<Vector3>();
        sourceVerts.AddRange(mf.sharedMesh.vertices);
        DrawMesh();

        m_camera.AddCommandBuffer(CameraEvent.AfterForwardOpaque, cb);


        quad = new Mesh();
        Vector3[] vertices = new Vector3[4];
        vertices[0] = m_camera.ScreenToWorldPoint(new Vector3(0, 0, 10));
        vertices[1] = m_camera.ScreenToWorldPoint(new Vector3(0, m_camera.pixelHeight, 10));
        vertices[2] = m_camera.ScreenToWorldPoint(new Vector3(m_camera.pixelWidth, m_camera.pixelHeight, 10));
        vertices[3] = m_camera.ScreenToWorldPoint(new Vector3(m_camera.pixelWidth, 0, 10));

        Vector2[] uvs = new Vector2[4];
        uvs[0] = new Vector2(0, 0);
        uvs[1] = new Vector2(0, 1);
        uvs[2] = new Vector2(1, 1);
        uvs[3] = new Vector2(1, 0);
        quad.vertices = vertices;
        quad.uv = uvs;

        int[] ids = new int[6];
        ids[0] = 0;
        ids[1] = 1;
        ids[2] = 2;
        ids[3] = 2;
        ids[4] = 3;
        ids[5] = 0;

        quad.triangles = ids;
//        CommandBuffer cb2 = new CommandBuffer();
//        cb2.name = "drawScreen";
//        Material material = new Material(sampleShader);
//        material.SetTexture("_MainTex", rt);
//        cb2.DrawMesh(quad, Matrix4x4.identity, material);
        //camera.AddCommandBuffer(CameraEvent.AfterImageEffects, cb2);
    }
}


